﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Pampa.CRUD.Configuration;
using Pampa.CRUD.Core;
using Pampa.MVC.Fluent.Crud.Groups;

namespace Pampa.MVC.Fluent.Crud.Items
{
    public class VisibleItemBuilder<TGroup, TEditor, TEntity, TThis> : ItemBuilder<TGroup, TEditor, TEntity> where TThis : VisibleItemBuilder<TGroup, TEditor, TEntity, TThis>
    {
        private readonly VisibleItem _visibleItem;

        public VisibleItemBuilder(VisibleItem visibleItem) : base(visibleItem)
        {
            _visibleItem = visibleItem;
        }

        public VisibleItemBuilder(GroupBuilder<TGroup, TEditor> group, VisibleItem visibleItem): base(group, visibleItem)
        {
            _visibleItem = visibleItem;
        }

        public TThis Label(string label)
        {
            _visibleItem.Label = label;
            return (TThis)this;
        }

        public TThis LabelWidth(int labelWidth)
        {
            _visibleItem.LabelWidth = labelWidth;
            return (TThis)this;
        }

        public TThis ValueWidth(int valueWidth)
        {
            _visibleItem.ValueWidth = valueWidth;
            return (TThis)this;
        }

        public TThis AddEditPermission(Func<TEditor, bool> action)
        {
            var guid = Guid.NewGuid().ToString();
            this.ParentGroup.ParentEditor.SecurityManager.AddEditRule(guid, action);
            _visibleItem.PermissionRequired = guid;
            return (TThis)this;
        }

        public TThis AddViewPermission(Func<TEditor, bool> action)
        {
            var guid = Guid.NewGuid().ToString();
            this.ParentGroup.ParentEditor.SecurityManager.AddViewRule(guid, action);
            _visibleItem.PermissionRequired = guid;
            return (TThis)this;
        }

        public TThis AddCustomPermission(string permision)
        {
            _visibleItem.PermissionRequired = permision;
            return (TThis)this;
        }

        /// <summary>
        /// Para propiedades no bindeadas se puede agregar una funcion que calcule el valor en runtime
        /// </summary>
        public TThis Value(Expression<Func<TGroup, object>> property)
        {
            EntityManager.AddCalculatedProperty(_visibleItem.Id, property);
            return (TThis)this;
        }
    }
}
